package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.dto.ReservationDto;
import com.zzyl.entity.Reservation;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.CustomerReservationMapper;
import com.zzyl.service.CustomerReservationService;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.ReservationVo;
import com.zzyl.vo.TimeCountVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class CustomerReservationServiceImpl implements CustomerReservationService {

    @Autowired
    private CustomerReservationMapper customerReservationMapper;

    // 获取预约取消次数
    @Override
    public Integer getCancelledCount(Long userId) {
        LocalDateTime time = LocalDateTime.now();
        LocalDateTime begin = LocalDateTimeUtil.beginOfDay(time);
        LocalDateTime end = LocalDateTimeUtil.endOfDay(time);

        Integer cancelledCount = customerReservationMapper.getCancelledCount(begin, end, userId);

        return cancelledCount;
    }

    // 这个方法将定时执行，例如每天每半小时执行一次
    /*@Scheduled(cron = "0 0,30 * * * ?")
    public void scheduleReservationCountUpdate() {
        // 假设您想要查询从当前时间开始到未来24小时内的剩余预约次数
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime endTime = now.plusHours(24);

        List<TimeCountVo> reservationCounts = getReservationCount(now, endTime);
        reservationCounts.forEach(System.out::println);
    }*/

    // 查询每个时间段的剩余预约次数
    @Override
    public int getReservationCount(LocalDateTime startTime, LocalDateTime endTime) {
        int count = customerReservationMapper.getReservationCount(startTime, endTime);
        return count;
    }

    // 分页查询预约记录
    @Override
    public PageResponse<ReservationVo> selectByPage(Integer pageNum, Integer pageSize, Long userId, Integer status) {

        PageHelper.startPage(pageNum, pageSize);
        Page<ReservationVo> pages = customerReservationMapper.selectByPage(pageNum, pageSize, userId, status);

        return PageResponse.of(pages, ReservationVo.class);
    }

    // 添加预约
    /*
    当天取消预约次数超过3次，则不能预约。
    还有同一个手机号同一个时间段只能预约一次：phone  +  time
    RESERVATION_CANCEL_COUNT_UPPER_LIMIT*(1526, "今天取消次数已达上限，不可进行预约")
    TIME_ALREADY_RESERVATED_BY_PHONE*(1527, "此手机号已预约该时间")
     */
    @Override
    public ResponseResult addReservation(ReservationDto reservationDto) {
        LocalDateTime time = LocalDateTime.now();
        LocalDateTime begin = LocalDateTimeUtil.beginOfDay(time);
        LocalDateTime end = LocalDateTimeUtil.endOfDay(time);

        Long userId = UserThreadLocal.getUserId();

        // 获取当天取消预约次数
        Integer count = customerReservationMapper.getCancelledCount(begin, end, userId);
        if (count >= 3) {
            throw new BaseException(BasicEnum.RESERVATION_CANCEL_COUNT_UPPER_LIMIT);
        }

        String phone = reservationDto.getMobile();
        LocalDateTime reservationTime = reservationDto.getTime();
        Integer number = customerReservationMapper.getCancelledCountWithPhone(phone,reservationTime);
        if (number > 0) {
            throw new BaseException(BasicEnum.TIME_ALREADY_RESERVATED_BY_PHONE);
        }

        Reservation reservation = BeanUtil.copyProperties(reservationDto, Reservation.class);

        reservation.setCreateBy(userId);
        reservation.setUpdateBy(userId);
        reservation.setStatus(0);

        customerReservationMapper.addReservation(reservation);

        return ResponseResult.success();
    }

    // 取消预约
    @Override
    public void cancelReservation(Long id) {
        // 判断是否超时，如果超时，系统自动更新为已过期
        LocalDateTime time = LocalDateTime.now();
        // 获取预约时间
        LocalDateTime reservationTime = customerReservationMapper.getReservationTime(id);
        if (time.isBefore(reservationTime)) {
            Integer status = 2;
            customerReservationMapper.cancelReservation(id, status);
        } else {
            Integer status = 3;
            customerReservationMapper.autoCancelReservation(id, status);
        }
    }

    @Override
    public void updateReservationStatus(LocalDateTime now) {

    }


}
